package com.it.myd.service.main.module.wuziqi;

import com.it.myd.bean.box.UserGameInfo;
import com.it.myd.bean.box.game.WuziqiRV;
import com.it.myd.bean.box.game.Room;
import com.it.myd.bean.main.ReturnValue;
import com.it.myd.bean.main.User;
import com.it.myd.dao.main.UserDao;
import com.it.myd.dao.main.module.wuziqi.WuziqiDao;
import com.it.myd.service.main.module.room.RoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.*;

@Service
public class WuZiQiServiceImpl implements WuZiQiService{

    @Autowired
    WuziqiDao wuziqiDao;
    @Autowired
    UserDao userDao;
    @Autowired
    RoomService roomService;

    private Map<Integer, WebSocketSession> wsSessions = new HashMap<>();
    private Map<Integer, WebSocketSession> wsGameSessions = new HashMap<>();
    private Queue<UserGameInfo> normalQueue=new LinkedList<>();

    public void gamePlayerEntry(Integer userid,WebSocketSession session) {
        wsGameSessions.put(userid, session);
    }
    public WebSocketSession getgamePlayerSession(Integer userid){
        return wsGameSessions.get(userid);
    }
    public void gamePlayerOut(Integer userid) {
        wsGameSessions.remove(userid);
    }


    @Override
    public void cellQz(WuziqiRV wzqRV) {
        Room room = roomService.getRoomByUserId(Integer.valueOf(wzqRV.getUserid()));
        List<UserGameInfo> userList = room.getPlayers();
        for (UserGameInfo userGameInfo:userList){
            if(!wzqRV.getUserid().equals(String.valueOf(userGameInfo.getUser().getUser_id()))){
                WebSocketSession wss = getgamePlayerSession(userGameInfo.getUser().getUser_id());
                if(wss!=null){
                    try {
                        wss.sendMessage(new TextMessage(wzqRV.toJson()));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }

    }

    public void playeradd(UserGameInfo user, WebSocketSession session) {
        wsSessions.put(user.getUser().getUser_id(), session);
        synchronized (normalQueue) {
            normalQueue.offer(user);
            normalQueue.notify();
        }
        System.out.println("把玩家 " + user.getUser().getUser_name() + " 加入到了 normalQueue 中!");
    }
    // 当玩家点击停止匹配的时候, 就需要把玩家从匹配队列中删除
    public void playerremove(UserGameInfo user) {
        synchronized (normalQueue) {
            normalQueue.remove(user);
        }
        System.out.println("把玩家 " + user.getUser().getUser_name() + " 移除了 normalQueue!");
    }
    public WuZiQiServiceImpl(){
        Thread t1=new Thread(){
            @Override
            public  void run(){
                while (true){
                    handlerMatch(normalQueue);
                }
            }
        };
        t1.start();
    }

    private void handlerMatch(Queue<UserGameInfo> matchQueue) {
        synchronized (matchQueue) {
            try {
                while (matchQueue.size() < 2) {
                    matchQueue.wait();
                }
                // 尝试从队列中取出两个玩家
                UserGameInfo player1 = matchQueue.poll();
                UserGameInfo player2 = matchQueue.poll();
                System.out.println("匹配出两个玩家: " + player1.getUser().getUser_name() + ", " + player2.getUser().getUser_name());
                //获取到玩家的 websocket 的会话
                //获取到会话的目的是为了告诉玩家, 你排到了~~
                WebSocketSession session1 = wsSessions.get(player1.getUser().getUser_id());
                WebSocketSession session2 = wsSessions.get(player2.getUser().getUser_id());

                // 前面的逻辑里进行了处理, 当玩家断开连接的时候就把玩家从匹配队列中移除了.
                if (session1 == null) {
                    // 如果玩家1 现在不在线了, 就把玩家2 重新放回到匹配队列中
                    matchQueue.offer(player2);
                    return;
                }
                if (session2 == null) {
                    // 如果玩家2 现在下线了, 就把玩家1 重新放回匹配队列中
                    matchQueue.offer(player1);
                    return;
                }

                if (session1 == session2) {
                    // 把其中的一个玩家放回匹配队列.
                    matchQueue.offer(player1);
                    return;
                }

                //  把这两个玩家放到一个游戏房间中.
                Room room = new Room();
                room.setType("1");
                addGameInfo(room);
                List<Integer> idlist = new ArrayList<>();
                idlist.add(player1.getUser().getUser_id());
                idlist.add(player2.getUser().getUser_id());
                roomService.add(room,idlist);


                //    此处是要给两个玩家都返回 "匹配成功" 这样的信息.
                //    因此就需要返回两次
                ReturnValue ret = new ReturnValue();
                ret.isSuccess("匹配成功");
                ret.setRetDesc1(room.getRoom_id());
                session1.sendMessage(new TextMessage(ret.toJson()));
                session2.sendMessage(new TextMessage(ret.toJson()));
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<UserGameInfo> getUserGameInfo(UserGameInfo userGameInfo) {
        return wuziqiDao.getUserGameInfo(userGameInfo);
    }

    @Override
    public void addUserGameInfo(UserGameInfo userGameInfo) {
        wuziqiDao.insertUserGameInfo(userGameInfo);
    }

    @Override
    public List<User> getUserByUserid(String userid) {
        return userDao.getUserByUserid(userid);
    }

    @Override
    public void updateUserGameInfo(UserGameInfo userGameInfo) {
        wuziqiDao.updateUserGameInfo(userGameInfo);
    }
    @Override
    public void addGameInfo(Room room) {
        wuziqiDao.insertGameInfo(room);
    }
    @Override
    public void updateGameInfo(Room room) {
        wuziqiDao.updateGameInfo(room);
    }
}
